import type { AxiosError, InternalAxiosRequestConfig } from 'axios'
import axios from 'axios'
import { showNotify } from 'vant'
import { STORAGE_TOKEN_KEY } from '@/stores/mutation-type'

// 这里是用于设定请求后端时，所用的 Token KEY
// 可以根据自己的需要修改，常见的如 Access-Token，Authorization
// 需要注意的是，请尽量保证使用中横线`-` 来作为分隔符，
// 避免被 nginx 等负载均衡器丢弃了自定义的请求头
// 这里是用于设定请求后端时，所用的 Token KEY
// 可以根据自己的需要修改，常见的如 Access-Token，Authorization
// 需要注意的是，请尽量保证使用中横线`-` 来作为分隔符，
// 避免被 nginx 等负载均衡器丢弃了自定义的请求头
export const REQUEST_TOKEN_KEY = 'Access-Token'

// 注意：这里使用 STORAGE_TOKEN_KEY 来保持一致性
// STORAGE_TOKEN_KEY = 'access_token'，但请求头使用 'Access-Token'

// JWT Token 请求头格式
export const JWT_AUTHORIZATION_HEADER = 'Authorization'

// 创建 axios 实例
function resolveApiBaseUrl(): string {
  try {
    // 优先读取本地保存的配置（config-manager 写入）
    const saved = localStorage.getItem('APP_CONFIG')
    if (saved) {
      const cfg = JSON.parse(saved)
      if (cfg && typeof cfg.API_SERVER_URL === 'string' && cfg.API_SERVER_URL) {
        return cfg.API_SERVER_URL
      }
    }
  } catch {}
  // 其次读取运行时注入的 window.APP_CONFIG
  try {
    const url = (window as any).APP_CONFIG?.API_SERVER_URL
    if (typeof url === 'string' && url) return url
  } catch {}
  // 兜底为空串，保持与原行为一致
  return ''
}

const request = axios.create({
  // API 请求的默认前缀：统一来自 public/config.js
  baseURL: resolveApiBaseUrl(),
  timeout: 6000, // 请求超时时间
})

export type RequestError = AxiosError<{
  message?: string
  msg?: string
  result?: any
  errorMessage?: string
}>

// 自定义业务错误类型
export interface BusinessError extends Error {
  code: number
  data?: any
}

// 异常拦截处理器
function errorHandler(error: RequestError): Promise<any> {
  if (error.response) {
    const { data = {}, status, statusText } = error.response
    // 403 无权限
    if (status === 403) {
      showNotify({
        type: 'danger',
        message: (data && data.message) || statusText,
      })
    }
    // 401 未登录/未授权 或者 token被挤下线
    if (status === 401) {
      // 清除本地数据
      localStorage.removeItem(STORAGE_TOKEN_KEY)
      localStorage.removeItem('user_info')
      localStorage.removeItem('user_tokens')
      
      const message = (data && (data.msg || data.message)) || '登录已失效，请重新登录'
      showNotify({
        type: 'danger',
        message: message,
      })
      
      // 跳转到登录页面
      if (window.location.pathname !== '/login') {
        window.location.href = '/login'
      }
    }
  }
  return Promise.reject(error)
}

// 检查token是否过期（模拟）
function isTokenExpired(token) {
  if (!token) return true
  
  // 如果token不是预期的格式，假设未过期（让后端判断）
  if (!token.includes('_') || token.split('_').length < 3) {
    return false
  }
  
  try {
    const tokenParts = token.split('_')
    const timestamp = parseInt(tokenParts[2])
    
    // 检查时间戳是否有效
    if (isNaN(timestamp) || timestamp <= 0) {
      return false
    }
    
    const now = Date.now()
    const expireTime = 24 * 60 * 60 * 1000 // 24小时过期
    
    return (now - timestamp) > expireTime
  } catch (error) {
    // 如果解析失败，假设未过期（让后端判断）
    console.warn('Token格式解析失败:', error)
    return false
  }
}

// 请求拦截器
function requestHandler(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig> {
  // logout 接口跳过拦截器逻辑
  if (config.url === '/user/logout') {
    return config
  }
  
  const savedToken = localStorage.getItem(STORAGE_TOKEN_KEY)
  console.log('从localStorage获取token:', savedToken, '使用键名:', STORAGE_TOKEN_KEY)
  // 检查token是否过期
  if (savedToken && isTokenExpired(savedToken)) {
    // token过期，清除本地数据并跳转到登录页
    localStorage.removeItem(STORAGE_TOKEN_KEY)
    localStorage.removeItem('user_info')
    localStorage.removeItem('user_tokens')
    
    showNotify({
      type: 'warning',
      message: '登录已过期，请重新登录'
    })
    
    // 跳转到登录页
    if (window.location.pathname !== '/login') {
      window.location.href = '/login'
    }
    
    return Promise.reject(new Error('Token expired'))
  }
  
  // 如果 token 存在且未过期
  if (savedToken) {
    // 添加原有的 Access-Token 请求头（保持向后兼容）
    config.headers[REQUEST_TOKEN_KEY] = savedToken
    
    // 添加 JWT Token 到 Authorization 请求头
    config.headers[JWT_AUTHORIZATION_HEADER] = `Bearer ${savedToken}`
    
    // 尝试其他可能的请求头格式
    config.headers['token'] = savedToken
    config.headers['x-access-token'] = savedToken
    config.headers['x-auth-token'] = savedToken
    
    // 尝试不带Bearer前缀的Authorization
    config.headers['Authorization-Raw'] = savedToken
    
    // 尝试其他常见的认证请求头
    config.headers['X-API-Key'] = savedToken
    config.headers['X-Requested-With'] = 'XMLHttpRequest'
    
    // 对于POST请求，确保认证头不被覆盖
    if (config.method?.toLowerCase() === 'post') {
      console.log('⚠️ POST请求，确保认证头不被覆盖')
      // 强制设置认证头，防止被其他逻辑覆盖
      Object.assign(config.headers, {
        [REQUEST_TOKEN_KEY]: savedToken,
        [JWT_AUTHORIZATION_HEADER]: `Bearer ${savedToken}`,
        'token': savedToken,
        'x-access-token': savedToken,
        'x-auth-token': savedToken,
        'Authorization-Raw': savedToken,
        'X-API-Key': savedToken,
        'X-Requested-With': 'XMLHttpRequest'
      })
    }
    
    console.log('添加认证请求头:', {
      [REQUEST_TOKEN_KEY]: savedToken,
      [JWT_AUTHORIZATION_HEADER]: `Bearer ${savedToken}`,
      'token': savedToken,
      'x-access-token': savedToken,
      'x-auth-token': savedToken,
      'Authorization-Raw': savedToken,
      'X-API-Key': savedToken,
      'X-Requested-With': 'XMLHttpRequest'
    })
    
    // 打印完整的请求配置，帮助调试
    console.log('完整请求配置:', {
      url: config.url,
      method: config.method,
      headers: config.headers,
      baseURL: config.baseURL
    })
  }

  return config
}

// Add a request interceptor
request.interceptors.request.use(requestHandler, errorHandler)

// 响应拦截器
function responseHandler(response: { data: any }) {
  const { data } = response
  
  // 后端使用 code: 0 表示成功
  if (data && typeof data.code !== 'undefined') {
    if (data.code === 0) {
      // 成功情况，直接返回后端的data结构
      return data
    } else {
      // 业务错误，抛出异常
      const error = new Error(data.msg || data.message || '请求失败') as BusinessError
      error.code = data.code
      error.data = data
      throw error
    }
  }
  
  // 兼容没有包装的响应
  return data
}

// Add a response interceptor
request.interceptors.response.use(responseHandler, errorHandler)

export default request
